home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software of the Month Club 1996 June
/
Software of the Month Club 1996 June.iso
/
pc
/
dos
/
dtp
/
display
/
drvsrc
/
ibm8514a.c
< prev
next >
Wrap
Text File
|
1994-02-22
|
6KB
|
228 lines
/*
* ibm8514a.c - Shell to initialize the 8514/A
* Written by Jake Richter
* Copyright (c) 1989,1990 Panacea Inc., Londonderry, NH
*
* This program may be freely distributed and modified.
*/
#include <dos.h>
#include "reg8514a.h"
int status_8514A = (-1); /* -1: not present, 0: VGA, 1: enabled */
/*
* check_8514A()
* =============
* Check to see if an 8514/A is actually installed by
* writing to the ERR_TERM register, and reading back. The
* 0x5A5A value is entirely arbitrary.
*/
int check_8514A(void)
{
int status;
outpw(ERR_TERM,0x5A5A);
if(inpw(ERR_TERM) != 0x5A5A) return(0);
outpw(ADVFUNC_CNTL,6); /* make sure we are in VGA mode */
/*
* Reset the 8514/A, and disable all interrupts.
*/
outpw(SUBSYS_CNTL,GPCTRL_RESET | CHPTEST_NORMAL);
outpw(SUBSYS_CNTL,GPCTRL_ENAB | CHPTEST_NORMAL);
/*
* Get board status information.
*/
status = inpw(SUBSYS_STAT);
/*
* Check if we can do 1024x768 with 256 colors.
* If not, don't bother with 8514A modes.
*/
if((status & MONITORID_MASK) != MONITORID_8514) return(0);
if((status & _8PLANE) == 0) return(0);
/*
* OK, it's present and the modes we want are available
*/
status_8514A = 0;
return(1);
}
/*
* disable_8514A()
* ===============
*
* go back to VGA mode
*/
void disable_8514A(void)
{
if(status_8514A > 0) {
outpw(ADVFUNC_CNTL,6); /* Return to VGA Mode */
status_8514A = 0;
}
}
/*
* InitLUT()
* =========
* Loads the Look-up Table with ramps of red, green, blue, and gray.
* Assumes 8-bit board is in use. If 4 bit board, then only the first
* 16 entries in LUT will be used. Could be written more compact, but
* has been expanded for greater readability.
*/
LUTENTRY lutData[16] = { /* approximate default VGA colors */
0x00, 0x00, 0x00, /* Black */
0x00, 0x00, 0x7f, /* Dark Blue */
0x00, 0x7f, 0x00, /* Dark Green */
0x00, 0x7f, 0x7f, /* Dark Cyan */
0x7f, 0x00, 0x00, /* Dark Red */
0x7f, 0x00, 0x7f, /* Dark Magenta */
0x7f, 0x7f, 0x00, /* Dark Yellow (Brown) */
0x7f, 0x7f, 0x7f, /* Gray */
0x1f, 0x1f, 0x1f, /* Dark Gray (Almost Black) */
0x00, 0x00, 0xff, /* Bright Blue */
0x00, 0xff, 0x00, /* Bright Green */
0x00, 0xff, 0xff, /* Bright Cyan */
0xff, 0x00, 0x00, /* Bright Red */
0xff, 0x00, 0xff, /* Bright Magenta */
0xff, 0xff, 0x00, /* Bright Yellow */
0xff, 0xff, 0xff /* White */
};
static void InitLUT(void)
{
int ii,jj;
/*
* Start by setting the DAC Write Index to 0.
*/
outp(DAC_W_INDEX,0);
/*
* Load all 256 LUT entries (pattern repeats after every 16 colors)
*/
for(ii = 0; ii < 16; ii++) {
for(jj = 0; jj < 16; jj++) {
outp(DAC_DATA,lutData[jj].r >> 2);
outp(DAC_DATA,lutData[jj].g >> 2);
outp(DAC_DATA,lutData[jj].b >> 2);
}
}
}
/*
* InitEnvironment()
* =================
*
* Initializes the 8514/A's drawing environment and clears the display.
*/
void InitEnvironment(void)
{
/*
* Current mixes, replace, foreground active
*/
outpw(FRGD_MIX,FSS_FRGDCOL | MIX_REPLACE);
outpw(BKGD_MIX,BSS_BKGDCOL | MIX_REPLACE);
/*
* Clipping rectangle to full drawable space (0,0 to 1023, 1023).
*/
outpw(MULTIFUNC_CNTL,SCISSORS_T | 0x000);
outpw(MULTIFUNC_CNTL,SCISSORS_L | 0x000);
outpw(MULTIFUNC_CNTL,SCISSORS_B | 0x3FF);
outpw(MULTIFUNC_CNTL,SCISSORS_R | 0x3FF);
/*
* Enable writes to all planes and reset color compare
*/
outpw(WRT_MASK,0xFFFF);
outpw(MULTIFUNC_CNTL,PIX_CNTL | 0x0000); /* Clear lower bits */
/*
* Clear the display. Need to set the color, origin, and size.
* Then draw. See Listing 7-5 for more information.
*/
WaitQueue(6);
outpw(FRGD_COLOR,0);
outpw(CUR_X,0);
outpw(CUR_Y,0);
outpw(MAJ_AXIS_PCNT,1023);
outpw(MULTIFUNC_CNTL,MIN_AXIS_PCNT | 1023);
outpw(CMD,CMD_RECT | INC_Y | INC_X | DRAW | PLANAR | WRTDATA);
/*
* Reset current draw position
*/
WaitQueue(4);
outpw(CUR_X,0x0000);
outpw(CUR_Y,0x0000);
/*
* Reset current colors, foreground is all on, background is 0.
*/
outpw(FRGD_COLOR,0xFFFF);
outpw(BKGD_COLOR,0x0000);
}
/*
* setup_8514A_256_color_mode()
* ============================
* Initializes the 8514/A into the requested resolution. Valid input
* values are 0 for 640x480 and 1 for 1024x768.
*
* No error checking on input value is performed. If an 8514/A is not
* found, or if the 1024 mode is selected, but an appropriate monitor
* is not available, this routine will print a message and exit to DOS.
*/
#define MODE_640 0
#define MODE_1024 1
int initRegs[] = {
DISP_CNTL, ADVFUNC_CNTL, V_TOTAL, V_SYNC_STRT,
V_DISP, H_TOTAL, H_SYNC_STRT, H_DISP,
H_SYNC_WID, V_SYNC_WID, DISP_CNTL, 0
};
int mode640x8[] = {
0x0043, 0x0003, 0x0418, 0x03D2,
0x03BB, 0x0063, 0x0052, 0x004F,
0x002C, 0x0022, 0x0023
};
int mode1024x8[] = {
0x0053, 0x0007, 0x0660, 0x0600,
0x05FB, 0x009D, 0x0081, 0x007F,
0x0016, 0x0008, 0x0033
};
void setup_8514A_256_color_mode(int res)
{
int ii;
/*
* Blank the screen temporarily to display color 0 by turning
* the display of all planes off.
*/
outp(DAC_MASK,0x00);
/*
* Reset the 8514/A, and disable all interrupts.
*/
outpw(SUBSYS_CNTL,GPCTRL_RESET | CHPTEST_NORMAL);
outpw(SUBSYS_CNTL,GPCTRL_ENAB | CHPTEST_NORMAL);
outpw(MULTIFUNC_CNTL,MEM_CNTL | VRTCFG_4 | HORCFG_8);
/*
* Now initialize the display controller part of the 8514/A.
* We have set up the initialization values in two sets of
* tables: 4 bpp and 8 bpp. The "numPlanes" comparison below
* determines which set of values to use (dual indices).
*/
for(ii = 0; initRegs[ii] != 0; ii++) {
int regno = initRegs[ii];
outpw(regno,(res == MODE_1024) ? mode1024x8[ii] : mode640x8[ii]);
}
/*
* Now reenable the screen, but only the planes that actually exist.
* Otherwise, you end up with bus noise on the display.
*/
InitLUT();
InitEnvironment();
outpw(DAC_MASK,0xFF); /* Enable all 8 planes for display */
status_8514A = 1;
}